﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
#region WaveEngineStuffs
using WaveEngine.Common;
using WaveEngine.Common.Graphics;
using WaveEngine.Common.Helpers;
using WaveEngine.Common.Input;
using WaveEngine.Common.IO;
using WaveEngine.Common.Math;
using WaveEngine.Common.Media;
using WaveEngine.Common.System;
using WaveEngine.Components;
using WaveEngine.Components.Animation;
using WaveEngine.Components.Cameras;
using WaveEngine.Components.Graphics2D;
using WaveEngine.Components.Particles;
using WaveEngine.Components.Resources;
using WaveEngine.Components.UI;
using WaveEngine.Framework;
using WaveEngine.Framework.Animation;
using WaveEngine.Framework.Graphics;
using WaveEngine.Framework.Managers;
using WaveEngine.Framework.Physics2D;
using WaveEngine.Framework.Services;
using WaveEngine.Framework.Sound;
using WaveEngine.Framework.UI;
using WaveEngine.Graphics;
using WaveEngine.Materials;
#endregion
using Lidgren.Network;
using System.Threading;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace NetworkedGameProject
{
    public class NetworkManager : SceneBehavior
    {
        private NetClient Client;
        private bool Ready;
        public List<Player> Players;

        public NetworkManager()
            :base("NetworkManager")
        {
            Ready = false;
            NetPeerConfiguration config = new NetPeerConfiguration("NetworkedGame");
            Client = new NetClient(config);
            Client.Start();
            NetOutgoingMessage outmsg = Client.CreateMessage();
            outmsg.Write((byte)Headers.Login);
            Client.Connect("127.0.0.1", 7777, outmsg);
            Players = new List<Player>();
            Thread thrdInit = new Thread(new ThreadStart(WaitForStartingInfo));
            thrdInit.Start();
        }

        private void WaitForStartingInfo()
        {
            bool canStart = false;
            NetIncomingMessage incmsg;

            while (!canStart)
            {
                if ((incmsg = Client.ReadMessage()) != null)
                {
                    switch (incmsg.MessageType)
                    {
                        case NetIncomingMessageType.Data:

                            if (incmsg.ReadByte() == (byte)Headers.WorldData)
                            {
                                Players.Clear();
                                int count = incmsg.ReadInt32();

                                for (int i = 0; i < count; i++)
                                {
                                    Player player = new Player(0.0f, null);
                                    incmsg.ReadAllProperties(player, System.Reflection.BindingFlags.Public);
                                    Console.WriteLine("[PROBLEM] PosX: {0}, Connection: {1}", player.PosX, player.Connection);
                                    Players.Add(player);
                                }

                                canStart = true;
                            }
                            break;

                        default:

                            Console.WriteLine(incmsg.ReadString() + " Strange message");
                            break;
                    }

                    Client.Recycle(incmsg);
                }
            }

            //Ready = true;
        }

        public void Receive()
        {
            //throw new NotImplementedException();
            NetIncomingMessage incmsg;

            while ((incmsg = Client.ReadMessage()) != null)
            {
                if (incmsg.MessageType == NetIncomingMessageType.Data)
                {
                    if (incmsg.ReadByte() == (byte)Headers.WorldData)
                    {
                        Players.Clear();
                        int count = incmsg.ReadInt32();

                        for (int i = 0; i < count; i++)
                        {
                            Player player = new Player(0.0f, null);
                            incmsg.ReadAllProperties(player, System.Reflection.BindingFlags.Public);
                            Console.WriteLine("[RECEIVE] PosX: {0}, Connection: {1}", player.PosX, player.Connection);
                            Players.Add(player);
                        }
                    }
                }

                Client.Recycle(incmsg);
            }
        }

        public void Sync(Player player)
        {
            NetOutgoingMessage outmsg = Client.CreateMessage();
            outmsg.Write((byte)Headers.PlayerData);
            outmsg.Write(player.PosX);
            Client.SendMessage(outmsg, NetDeliveryMethod.UnreliableSequenced);
        }

        protected override void ResolveDependencies()
        {
         
        }

        protected override void Update(TimeSpan gameTime)
        {
            if (Ready)
            {
                Receive();
            }
        }
    }
}
